package com.hedl.practice.diyJava.multithreading.thread_synchronization.example;

public class Study_3 {

    /**
     * 4个线程对两个共享变量分别进行读写操作，但是使用的锁都是Counter.lock这一个对象，
     * 这就造成了原本可以并发执行的Counter.studentCount += 1和Counter.teacherCount += 1，
     * 现在无法并发执行了，执行效率大大降低。
     *
     * 实际上，需要同步的线程可以分成两组：AddStudentThread和DecStudentThread，AddTeacherThread和DecTeacherThread，组之间不存在竞争，因此，应该使用两个不同的锁：
     *      AddStudentThread和DecStudentThread使用lockStudent锁
     *      AddTeacherThread和DecTeacherThread使用lockTeacher锁：
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        //把要创建的对象放入数组；循环创建
        var ts = new Thread[] { new AddStudentThread(), new DecStudentThread(), new AddTeacherThread(), new DecTeacherThread() };
        for (var t : ts) {
            t.start();  //循环启动
        }
        for (var t : ts) {
            t.join();   //循环等待线程
        }
        System.out.println(Counter_2.studentCount);
        System.out.println(Counter_2.teacherCount);
    }
}

class Counter_2 {
    public static final Object lock = new Object();
    public static int studentCount = 0;
    public static int teacherCount = 0;
}

class AddStudentThread extends Thread {
    public void run() {
        for (int i=0; i<10000; i++) {
            synchronized(Counter_2.lock) {
                Counter_2.studentCount += 1;
            }
        }
    }
}

class DecStudentThread extends Thread {
    public void run() {
        for (int i=0; i<10000; i++) {
            synchronized(Counter_2.lock) {
                Counter_2.studentCount -= 1;
            }
        }
    }
}

class AddTeacherThread extends Thread {
    public void run() {
        for (int i=0; i<10000; i++) {
            synchronized(Counter_2.lock) {
                Counter_2.teacherCount += 1;
            }
        }
    }
}

class DecTeacherThread extends Thread {
    public void run() {
        for (int i=0; i<10000; i++) {
            synchronized(Counter_2.lock) {
                Counter_2.teacherCount -= 1;
            }
        }
    }
}
